#include "layerprocess.h"
#include <stdlib.h>
#include <QTime>
#include <QMessageBox>

#define DICO_SETTING	"LastDico"


typedef enum{
		e_WordList_Word,
		e_WordList_Translation,
		e_WordList_EnumSize
}e_WordList;


LayerProcess::LayerProcess()
{
	/* Initialize the data layer access */
	pData = new LayerData();
}


void LayerProcess::displayAllWords(QTableWidget *widget)
{
	Word curWord;
	int dicoLength = pData->getDicoLength();
	int rowCount = 0;
	widget->clearContents();
	
	for(int i=0; i < dicoLength; i++)
	{
		curWord = pData->getWord(i);
		
		if(curWord.translation->length() > curWord.word->length())
			rowCount = rowCount + curWord.translation->length();
		else
			rowCount = rowCount + curWord.word->length();
			
		widget->setRowCount(rowCount);
		
		for(int j=0; j < curWord.word->length(); j++)
		{
			widget->setItem( i + j ,	0, new QTableWidgetItem( curWord.word->at(j)		) );
		}
		
		for(int j = 0; j < curWord.translation->length(); j++)
		{
			widget->setItem( i + j,		1, new QTableWidgetItem( curWord.translation->at(j)	) );
		}
		
		
	}

}


void LayerProcess::displayDicos(QComboBox *combo)
{
	QStringList dicos = pData->getDicos();
	dicos.sort();
	dicos<<"+ Add Dictionary";
	dicos.replaceInStrings(".csv","");
	dicos.replaceInStrings("Voca_","");
	
	combo->clear();
	combo->addItems(dicos);
}


void LayerProcess::LoadDico(QString dicoName)
{
	if(pData->loadDico("Voca_"+dicoName+".csv"))
		SaveCurDico(dicoName);
}


bool LayerProcess::checkDicoInit()
{
	bool isDicoInit = false;
	
	if(pData->getDicoLength())
		isDicoInit	= true;
	
	return isDicoInit;
}


QString LayerProcess::LoadLastDico()
{
	QString ret = pData->LoadIniSetting(DICO_SETTING);
	
	LoadDico(ret);
	
	return ret;
}


void LayerProcess::SaveCurDico(QString dicoName)
{
	pData->SaveIniSetting(DICO_SETTING, dicoName);
}


void LayerProcess::ClearDico()
{
	pData->ClearDico();
}


void LayerProcess::CreateDico(QString dicoName)
{
	/*ATTENTION: Ajouter une verif sur les caracteres speciaux */
	if(dicoName != "")
		pData->SaveDico("Voca_"+dicoName+".csv");
	
}


/**
  *@brief	Ajoute un mot dans le dictionnaire.
  *@return	true	si tout c'est bien passe.
  * 		false	si le mot contient des caracteres non autorises.
  */
bool LayerProcess::AddWord(QString newWord, QString newTranslation)
{
	bool ret = false;
	Word newWordData;
	
	if( (!newWord.contains("@")) && (!newTranslation.contains("@")) )
	{
		(*newWordData.word)<<newWord;
		(*newWordData.translation)<<newTranslation;
		
		if(pData->AddWord(newWordData))
			ret = true;
	}
	
	return ret;
}


bool LayerProcess::DeleteWord(int idx)
{
	bool ret = false;
	
	if(idx < pData->getDicoLength())
		ret = pData->DeleteWord(idx);
	
	return ret;
}


void LayerProcess::game_Init(QProgressBar *_uiProgress, QProgressBar *_uiProgress2)
{
	params_game.uiProgress			= _uiProgress;
	params_game.uiProgressResult	= _uiProgress2;
	
	params_game.wordSize = pData->getDicoLength() * e_WordList_EnumSize;
	
	/* Allocation memoire pour le tableau de mots aleatoire */
	params_game.pWordIdx = (int*)malloc( params_game.wordSize * sizeof(int) );
	
	/* Initialise un tableau pointant sur chaque mot */
	for(int i = 0; i < params_game.wordSize; i++)
		params_game.pWordIdx[i] = i;
	
	/* Initialise les pointeurs sur le tableau contenant les indices des mots */
	params_game.uiProgress->setMaximum(params_game.wordSize);
	params_game.uiProgress->setValue(0);
	params_game.uiProgressResult->setValue(0);
	params_game.lastWordIdx = params_game.wordSize-1;
	params_game.wordIdx		= 0;
	params_game.totalTries	= 0;
	
}


void LayerProcess::game_randomizeWords()
{
	QDateTime dtUTC = QDateTime::currentDateTime();
	
	/* rend aleatoire par l'algorithme Fisher-Yates */
	srand((int)dtUTC.toTime_t());
	int j = 0;
	for(int i = params_game.wordSize-1; i > 0; i--)
	{
		j = rand() % i;
		swap(&params_game.pWordIdx[j], &params_game.pWordIdx[i]);
	}

}


QString	LayerProcess::game_GetWord()
{
	QString ret = "";
	int wordIndex = params_game.pWordIdx[params_game.wordIdx];
	/* Recupere le mot genere aleatoirement */
	params_game.curWord = pData->getWord(wordIndex>>1);
	
	/* Verifie si l'aleatoire est tombe sur un mot ou une traduction */
	switch(wordIndex%e_dico_structure_enumSize)
	{
	case e_dico_structure_word:
		
		ret = params_game.curWord.word->at(0);
		/* Recupere la reponse en meme temps */
		params_game.curAnswer = params_game.curWord.translation->at(0);
		
		break;
	case e_dico_structure_translation:
		
		ret = params_game.curWord.translation->at(0);
		/* Recupere la reponse en meme temps */
		params_game.curAnswer = params_game.curWord.word->at(0);
		
		break;
	default:
		ret = "ERROR";
		break;
	}
	
	return ret;
}


QString LayerProcess::game_GetWordResult()
{
	return params_game.curAnswer;
}


bool LayerProcess::game_GetResult(QString answer)
{
	bool ret = false;
	
	/* check if the answer is correct */
	if(answer == params_game.curAnswer)
	{
		ret = true;
		params_game.wordIdx++;
	}
	else
	{
		swap(&params_game.pWordIdx[params_game.lastWordIdx], &params_game.pWordIdx[params_game.wordIdx]);
		for(int i = params_game.lastWordIdx; i < params_game.wordSize-1; i++)
			swap(&params_game.pWordIdx[i], &params_game.pWordIdx[i+1]);
	
		params_game.lastWordIdx--;
	}

	game_ResultCounter();
	
	/* Verification du debordement des parametres */
	if(!(params_game.lastWordIdx > params_game.wordIdx))
	{
		/* Reinitialise le pointeur sur le dernier mot non faux, pour redemarrer la gestion d'une nouvelle serie d'erreurs */
		params_game.lastWordIdx = params_game.wordSize-1;
	}
	if(!(params_game.wordIdx < params_game.wordSize))
		params_game.wordIdx = 0;
	
	return ret;
	
}


void LayerProcess::game_ResultCounter()
{
	float resultPercent;
	
	params_game.totalTries++;
	
	resultPercent = (float)(params_game.wordIdx) / (float)params_game.totalTries;

	params_game.uiProgress->setValue(params_game.wordIdx);
	params_game.uiProgressResult->setValue( (int)(resultPercent*100.0) );
	
}


void LayerProcess::game_close()
{
	free(params_game.pWordIdx);
}


/**
  @brief	Inverse 2 cellules pointant sur des entiers
  */
void LayerProcess::swap(int *pData1, int *pData2)
{
	*pData1 ^= *pData2;
	*pData2 ^= *pData1;
	*pData1 ^= *pData2;
}


void LayerProcess::PlaySound(e_Sounds soundName)
{
	switch(soundName)
	{
	case e_Sounds_Ok:
		pData->PlaySound("./Sounds/GlaconsVoca.wav");
		break;
	case e_Sounds_End:
		pData->PlaySound("./Sounds/washhVoca.wav");
		break;
	case e_Sounds_Pop:
		pData->PlaySound("./Sounds/champagneVoca.wav");
		break;
	default:
		break;
	}
}


LayerProcess::~LayerProcess()
{
	//game_close();

}
